package oa.hleast.xswl.service.place.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import oa.hleast.common.constant.CacheConstant;
import oa.hleast.common.constant.DictCodeConstant;
import oa.hleast.common.web.exception.BizException;
import oa.hleast.xswl.common.constant.CommonConstant;
import oa.hleast.xswl.mapper.place.PlaceRecommendMapper;
import oa.hleast.xswl.pojo.domain.SysDictItem;
import oa.hleast.xswl.pojo.domain.place.CmsPlaceRecommend;
import oa.hleast.xswl.pojo.dto.RecommendTypeDto;
import oa.hleast.xswl.pojo.form.place.CmsPlaceRecommendForm;
import oa.hleast.xswl.pojo.vo.place.CmsPlaceRecommendVo;
import oa.hleast.xswl.pojo.vo.place.HomePageRecommendVo;
import oa.hleast.xswl.pojo.vo.place.SelectPlaceRecommendVo;
import oa.hleast.xswl.service.ISysCommonConfigService;
import oa.hleast.xswl.service.ISysDictItemService;
import oa.hleast.xswl.service.ISysDictService;
import oa.hleast.xswl.service.IUmsUserService;
import oa.hleast.xswl.service.place.IPlaceRecommendService;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.cache.annotation.Caching;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 信息推荐表(CmsPlaceRecommend)表服务实现类
 *
 * @author 302
 * @since 2021-03-23 15:51:51
 */
@Slf4j
@AllArgsConstructor
@Service
public class PlaceRecommendServiceImpl extends ServiceImpl<PlaceRecommendMapper, CmsPlaceRecommend> implements IPlaceRecommendService {

    private final ISysCommonConfigService commonConfigService;
    private final ISysDictItemService dictItemService;
    private final ISysDictService dictService;
    private final IUmsUserService umsUserService;

    @Override
    @Cacheable(value = CacheConstant.HOME_PAGE_RECOMMEND_TYPE_KEY)
    public List<HomePageRecommendVo> findRecommendTypeList() {

        LambdaQueryWrapper<CmsPlaceRecommend> queryWrapper = new LambdaQueryWrapper<CmsPlaceRecommend>()
                .orderByDesc(CmsPlaceRecommend::getSort)
                .orderByDesc(CmsPlaceRecommend::getGmtModified)
                .orderByDesc(CmsPlaceRecommend::getGmtCreate);
        // table数据
        List<CmsPlaceRecommend> list = this.list(queryWrapper);

        List<HomePageRecommendVo> data = new ArrayList<>();

        //添加推荐
        HomePageRecommendVo firstData = HomePageRecommendVo.builder()
                .id(0L)
                .nameCn("婺城推荐")
                .intro("为您推荐")
                .selectType(CommonConstant.RECOMMEND_SELECT_TYPE)
                .build();
        data.add(firstData);
        for (CmsPlaceRecommend cmsPlaceRecommend : list) {
            data.add(conversionToHomePage(cmsPlaceRecommend));
        }
        log.info("从数据库中获取首页推荐table数据 data = {}", data);
        return data;
    }


    @Override
    public List<RecommendTypeDto> findRecommendType() {

        String code = DictCodeConstant.RECOMMEND_SELECT_TYPE;
        List<SysDictItem> dictItemList = dictItemService.getByDictByCode(code);
        List<RecommendTypeDto> recommendTypeDtoList = dictItemList.stream().map(dictItemValueDto -> {
            String value = dictItemValueDto.getValue();
            log.info("value = {}", value);
            RecommendTypeDto recommendTypeDto = new RecommendTypeDto();
            recommendTypeDto.setSelectType(value);
            recommendTypeDto.setDictItemId(dictItemValueDto.getId());
            recommendTypeDto.setNameCn(dictItemValueDto.getName());
            return RecommendTypeDto.builder()
                    .dictItemId(dictItemValueDto.getId())
                    .selectType(dictItemValueDto.getValue())
                    .nameCn(dictItemValueDto.getName())
                    .build();
        }).collect(Collectors.toList());
        return recommendTypeDtoList;
    }

    @Override
    public List<SelectPlaceRecommendVo> findRecommendSelectType() {
        LambdaQueryWrapper<CmsPlaceRecommend> queryWrapper = new LambdaQueryWrapper<CmsPlaceRecommend>()
                .orderByDesc(CmsPlaceRecommend::getSort)
                .orderByDesc(CmsPlaceRecommend::getGmtModified)
                .orderByDesc(CmsPlaceRecommend::getGmtCreate);

        List<CmsPlaceRecommend> list = this.list(queryWrapper);
        List<SelectPlaceRecommendVo> selectList = list.stream().map(pojo -> {

            SelectPlaceRecommendVo selectPlaceRecommendVo = new SelectPlaceRecommendVo();
            BeanUtil.copyProperties(pojo, selectPlaceRecommendVo);
            //获取中文名
            SysDictItem dictItem = dictItemService.getDictItemById(pojo.getDictItemId());
            if (ObjectUtils.isNotEmpty(dictItem)) {
                selectPlaceRecommendVo.setNameCn(dictItem.getName());
            }

            return selectPlaceRecommendVo;
        }).collect(Collectors.toList());
        return selectList;
    }

    /**
     * =========== 基本方法 CRUD ==========
     */

    @Override
    @Caching(evict = {
            @CacheEvict(value = CacheConstant.HOME_PAGE_RECOMMEND_TYPE_KEY, allEntries = true)
    })
    public Boolean add(CmsPlaceRecommendForm placeRecommendForm) {
        CmsPlaceRecommend cmsPlaceAssociate = conversionToPojo(placeRecommendForm);
        boolean save = this.save(cmsPlaceAssociate);

        return save;
    }

    @Override
    @Caching(evict = {
            @CacheEvict(value = CacheConstant.HOME_PAGE_RECOMMEND_TYPE_KEY, allEntries = true)
    })
    public Boolean update(CmsPlaceRecommendForm placeRecommendForm) {

        //校验ID
        CmsPlaceRecommend cmsPlaceAssociateOld = this.getById(placeRecommendForm.getId());
        if (ObjectUtils.isEmpty(cmsPlaceAssociateOld)) {
            throw new BizException("没有找到该数据！");
        }

        CmsPlaceRecommend cmsPlaceAssociateType = new CmsPlaceRecommend();
        BeanUtil.copyProperties(placeRecommendForm, cmsPlaceAssociateType);
        cmsPlaceAssociateType.setId(cmsPlaceAssociateOld.getId());
        cmsPlaceAssociateType.setGmtModified(new Date());

        return this.updateById(cmsPlaceAssociateType);
    }

    @Override
    @Caching(evict = {
            @CacheEvict(value = CacheConstant.HOME_PAGE_RECOMMEND_TYPE_KEY, allEntries = true)
    })
    public Boolean deleteByIds(List<String> ids) {
        if (CollectionUtils.isFull(ids)) {
            throw new BizException("没有选择任何数据，请重新操作！");
        }

        return this.removeByIds(ids);
    }

    @Override
    public CmsPlaceRecommendVo detail(Long id) {

        CmsPlaceRecommend cmsPlaceAssociate = this.getById(id);

        CmsPlaceRecommendVo cmsPlaceAssociateVo = conversionToVo(cmsPlaceAssociate);

        return cmsPlaceAssociateVo;
    }

    @Override
    public Page<CmsPlaceRecommendVo> pageList(Integer page, Integer limit, String title) {
        LambdaQueryWrapper<CmsPlaceRecommend> queryWrapper = new LambdaQueryWrapper<CmsPlaceRecommend>()
                .orderByDesc(CmsPlaceRecommend::getSort)
                .orderByDesc(CmsPlaceRecommend::getGmtModified)
                .orderByDesc(CmsPlaceRecommend::getGmtCreate);

        if (ObjectUtils.isNotEmpty(title)) {
            queryWrapper.like(CmsPlaceRecommend::getTitle, title);
        }


        Page<CmsPlaceRecommend> cmsPlaceInfoPage = this.page(new Page<>(page, limit), queryWrapper);

        if (cmsPlaceInfoPage.getTotal() == 0) {
            return new Page<>(page, limit);
        }

        List<CmsPlaceRecommendVo> cmsPlaceInfoList = cmsPlaceInfoPage.getRecords().stream().map(this::conversionToVo).collect(Collectors.toList());

        Page<CmsPlaceRecommendVo> cmsPlaceRecommendVoPage = new Page<>(page, limit, cmsPlaceInfoPage.getTotal());
        cmsPlaceRecommendVoPage.setRecords(cmsPlaceInfoList);


        return cmsPlaceRecommendVoPage;
    }


    /**
     * =========== 私有方法 ===========
     */
    private CmsPlaceRecommend conversionToPojo(CmsPlaceRecommendForm placeRecommendForm) {
        if (ObjectUtils.isEmpty(placeRecommendForm)) {
            throw new BizException("提交表单数据为空");
        }

        CmsPlaceRecommend cmsPlaceAssociate = new CmsPlaceRecommend();
        BeanUtil.copyProperties(placeRecommendForm, cmsPlaceAssociate);

        return cmsPlaceAssociate;
    }

    private CmsPlaceRecommendVo conversionToVo(CmsPlaceRecommend placeRecommend) {
        if (ObjectUtils.isEmpty(placeRecommend)) {
            log.info("cmsPlaceRecommend 数据为空");
            return new CmsPlaceRecommendVo();
        }

        CmsPlaceRecommendVo cmsPlaceAssociateVo = new CmsPlaceRecommendVo();
        BeanUtil.copyProperties(placeRecommend, cmsPlaceAssociateVo);

        //获取中文名
        SysDictItem dictItem = dictItemService.getDictItemById(placeRecommend.getDictItemId());
        if (ObjectUtils.isNotEmpty(dictItem)) {
            cmsPlaceAssociateVo.setNameCn(dictItem.getName());
        }

        return cmsPlaceAssociateVo;
    }

    public HomePageRecommendVo conversionToHomePage(CmsPlaceRecommend pojo) {
        return HomePageRecommendVo.builder()
                .id(pojo.getId())
                .nameCn(pojo.getTitle())
                .intro(pojo.getIntro())
                .selectType(pojo.getSelectType())
                .build();
    }
}